package com.qbw.app.module.home.holder;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;

import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.model.LatLng;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.http.okhttp.HttpTask;
import com.lib.util.ResUtil;
import com.qbw.app.Constant;
import com.qbw.app.R;
import com.qbw.app.databinding.HomeHolderLocationBinding;
import com.qbw.app.manager.GeneralManager;
import com.qbw.app.manager.LocationManager;
import com.qbw.app.manager.MapManager;
import com.qbw.app.model.Address;
import com.qbw.app.model.Location;
import com.qbw.app.module.common.holder.CommonHolder;
import com.qbw.app.module.common.util.BaiduUtil;
import com.qbw.app.module.common.util.Gps;
import com.qbw.app.module.common.util.PositionUtil;
import com.qbw.app.module.vehicle.VehicleDataBindingAdapter;
import com.qbw.app.module.vehicle.activity.VehicleLocationActivity;
import com.qbw.app.request.impl.CommonRequest;
import com.qbw.l.L;
import com.qbw.log.XLog;
import com.qbw.spm.P;

import static com.qbw.app.Constant.KEY_MAP;
import static com.qbw.app.Constant.MAP_BAIDU;
import static com.qbw.app.Constant.MAP_DEFAULT;
import static com.qbw.app.Constant.MAP_GOOGLE;
import static com.qbw.app.Constant.VEHICLE_STATUS_DRIVING;

/**
 *
 * @author xiansx
 * @date 2020/10/20
 */
public class HomeLocationHolder extends CommonHolder<Location, HomeHolderLocationBinding> implements OnMapReadyCallback, BaiduUtil.Callback, View.OnClickListener {

    private boolean mUseBaidu;
    private GoogleMap mGoogleMap;
    private Overlay mBaiduMarker;
    private Marker mGoogleMarker;

    public HomeLocationHolder(Context context, ViewGroup viewParent) {
        super(context, R.layout.home_holder_location, viewParent);
    }

    @Override
    public void bindData(int position, Location data) {
        super.bindData(position, data);
        mBinding.ivMapCover.setOnClickListener(this);
        L.GL.d("vehiclenick[%s]", data.getVehicleNick());
        mBinding.setLocation(data);
        mBinding.executePendingBindings();
        updateGpsSignal();
        updateGsmSignal();

        if (!data.isInited()) {
            data.setInited(true);
            initMap();
        } else {
            updateUi();
        }
    }

    // 备用代码
    //        VehicleDataBindingAdapter.convertGpsToCurrentMapGps(gps.getWgLat(),
//                gps.getWgLon());
//            GeneralManager.getInstance()
//                          .getRequestManager()
//                          .getCommonRequest()
//                          .getAddress(String.valueOf(data.getLatitude84()),
//                                      String.valueOf(data.getLongitude84()),
//                                      this)
//                          .execute();

    private void updateUi() {
        Location location = mData;
        if (!location.isGpsValid() || location
                .getGpsTime() <= 0) {
            mBinding.tvTime.setVisibility(View.GONE);
        } else {
            mBinding.tvTime.setVisibility(View.VISIBLE);
        }

        if (!location.isGpsValid()) {
            mBinding.tvAddress.setText(R.string.no_gps_data);
        }

        android.location.Location mCurrentLocation = LocationManager.getInstance().getLastLocation();

        String map = P.getString(KEY_MAP, MAP_DEFAULT);
        switch (map) {
            case MAP_BAIDU:
                if (location.isGpsValid()) {
                    baiduAnimateAndAddMarker(true,
                            location.getLatitude(),
                            location.getLongitude(),
                            getTravelEndDrawable());
                } else {
                    L.GL.w("车辆位置无效，显示用户当前位置");
                    if(mCurrentLocation != null) {
                        baiduAnimateAndAddMarker(true,
                                mCurrentLocation.getLatitude(),
                                mCurrentLocation.getLongitude(),
                                0);
                    } else {
                        Gps gps = PositionUtil.gps84_to_bd09_byBaiduSdk(PositionUtil.BEIJING_LAT,
                                PositionUtil.BEIJING_LNG);
                        baiduAnimateAndAddMarker(true,gps.getWgLat(), gps.getWgLon(), 0);
                    }
                }
                break;
            case MAP_GOOGLE:
                if (location.isGpsValid()) {
                    googleAnimateAndAddMarker(location.getLatitude(),
                            location.getLongitude(),
                            getTravelEndDrawable());
                } else {
                    L.GL.w("车辆位置无效，显示用户当前位置");
                    if(mCurrentLocation != null) {
                        googleAnimateAndAddMarker(mCurrentLocation.getLatitude(),
                                mCurrentLocation.getLongitude(),
                                0);
                    } else {
                        //Gps gps = PositionUtil.gps84_To_Gcj02(PositionUtil.BEIJING_LAT,
                        //        PositionUtil.BEIJING_LNG);
                        //googleAnimateAndAddMarker(gps.getWgLat(), gps.getWgLon(), 0);
                        CameraUpdate cameraUpdate = CameraUpdateFactory.zoomTo(1);
                        mGoogleMap.moveCamera(cameraUpdate);
                    }
                }
                break;
            default:
                break;
        }
    }

    private void initMap() {
        String map = P.getString(KEY_MAP, MAP_DEFAULT);
        mUseBaidu = MAP_BAIDU.equals(map);
        if (mUseBaidu) {
            initBaidu();
        } else if (MAP_GOOGLE.equals(map)) {
            initGoogle();
        }
    }

    private void initBaidu() {
        mBinding.googleMapView.setVisibility(View.GONE);
        mBinding.bmapView.setVisibility(View.VISIBLE);
        mBinding.bmapView.showScaleControl(false);
        mBinding.bmapView.showZoomControls(false);

        BaiduMap map = mBinding.bmapView.getMap();
        // 清空
        map.clear();
        map.setMyLocationEnabled(true);
        map.setMyLocationConfiguration(new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL,
                                                                   true,
                                                                   BitmapDescriptorFactory.fromResource(
                                                                           R.drawable.travel_offline)));
        //map.setOnMapClickListener(mBadiuMapClickListener);
        MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(15.0f);
        map.setMapStatus(msu);

        //mLocationClient = new LocationClient(getApplicationContext());
        LocationClientOption option = new LocationClientOption();

        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选，设置定位模式，默认高精度
        //LocationMode.Hight_Accuracy：高精度；
        //LocationMode. Battery_Saving：低功耗；
        //LocationMode. Device_Sensors：仅使用设备；

        option.setCoorType("bd09ll");
        //可选，设置返回经纬度坐标类型，默认gcj02
        //gcj02：国测局坐标；
        //bd09ll：百度经纬度坐标；
        //bd09：百度墨卡托坐标；
        //海外地区定位，无需设置坐标类型，统一返回wgs84类型坐标

        option.setScanSpan(1000);
        //可选，设置发起定位请求的间隔，int类型，单位ms
        //如果设置为0，则代表单次定位，即仅定位一次，默认为0
        //如果设置非0，需设置1000ms以上才有效

        option.setOpenGps(true);
        //可选，设置是否使用gps，默认false
        //使用高精度和仅用设备两种定位模式的，参数必须设置为true

        option.setLocationNotify(true);
        //可选，设置是否当GPS有效时按照1S/1次频率输出GPS结果，默认false

        option.setIgnoreKillProcess(false);
        //可选，定位SDK内部是一个service，并放到了独立进程。
        //设置是否在stop的时候杀死这个进程，默认（建议）不杀死，即setIgnoreKillProcess(true)

        option.SetIgnoreCacheException(false);
        //可选，设置是否收集Crash信息，默认收集，即参数为false

        option.setWifiCacheTimeOut(5 * 60 * 1000);
        //可选，7.2版本新增能力
        //如果设置了该接口，首次启动定位时，会先判断当前WiFi是否超出有效期，若超出有效期，会先重新扫描WiFi，然后定位

        option.setEnableSimulateGps(false);
        //可选，设置是否需要过滤GPS仿真结果，默认需要，即参数为false

        //mLocationClient.setLocOption(option);
        //mLocationClient为第二步初始化过的LocationClient对象
        //需将配置好的LocationClientOption对象，通过setLocOption方法传递给LocationClient对象使用
        //更多LocationClientOption的配置，请参照类参考中LocationClientOption类的详细说明

        //mLocationClient.registerLocationListener(mBaiduLocationListener = new
        // ElecAreaAddActivity.MyBaiduLocationListener());

        //mLocationClient.start();
        //mLocationClient.requestLocation();
        mBinding.bmapView.getMap().setOnMapClickListener(new BaiduMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                VehicleLocationActivity.start(mContext, mData);
            }

            @Override
            public boolean onMapPoiClick(MapPoi mapPoi) {
                return false;
            }
        });
        updateUi();
        onResume();
    }

    private int getTravelEndDrawable() {
        /*int d = R.drawable.travel_offline;
        Location location = mBinding.getLocation();
        if (location == null *//*|| (location.getLatitude() == 0 && location.getLongitude() == 0)*//*) {
            return d;
        }*/
        Location location = mBinding.getLocation();
        return VehicleDataBindingAdapter.getTravelLocationEndDrawable1(location == null ? -1 : location
                .getDrivingState());
    }

    private void baiduAnimateTo(double latitude, double longitude) {
        if (latitude == 0 && longitude == 0) {
            L.GL.w("invalid location");
            return;
        }
        Gps gps = /*PositionUtil.gps84_To_Bd09(latitude, longitude)*/new Gps(latitude, longitude);
        MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(new LatLng(gps.getWgLat(),
                gps.getWgLon()));
        // 移动到某经纬度
        mBinding.bmapView.getMap().animateMapStatus(update);
    }

    /**
     * 移动到指定位置，并添加marker
     */
    private void baiduAnimateAndAddMarker(boolean animateTo,
                                          double latitude,
                                          double longitude,
                                          int positionDrawableRes) {
        if (latitude == 0 && longitude == 0) {
            L.GL.w("invalid location");
            return;
        }
        //Gps gps = PositionUtil.gps84_To_Bd09(latitude, longitude);
        Gps gps = new Gps(latitude, longitude);
        if (animateTo) {
            MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(new LatLng(gps.getWgLat(),
                    gps.getWgLon()));
            // 移动到某经纬度
            mBinding.bmapView.getMap().animateMapStatus(update);
        }

        if (positionDrawableRes > 0) {
            if (mBaiduMarker != null) {
                mBaiduMarker.remove();
            }
            //添加marker
            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(), positionDrawableRes);
            if (positionDrawableRes != R.drawable.travel_start && positionDrawableRes != R.drawable.travel_end && positionDrawableRes != R.drawable.travel_location) {
                bitmap = getDirectionBitmap(bitmap);
            }
            mBaiduMarker = mBinding.bmapView.getMap()
                    .addOverlay(new com.baidu.mapapi.map.MarkerOptions().anchor(
                            0.5f,
                            0.5f)
                            .position(
                                    new LatLng(
                                            gps.getWgLat(),
                                            gps.getWgLon()))
                            .icon(BitmapDescriptorFactory
                                    .fromBitmap(
                                            bitmap)));
            mBaiduMarker.setZIndex(6);
        }
    }

    private Bitmap getDirectionBitmap(Bitmap bitmap) {
        Location location = mBinding.getLocation();
        if (location == null) {
            return bitmap;
        }
        Matrix matrix = new Matrix();
        int bw = bitmap.getWidth();
        int bh = bitmap.getHeight();
        //matrix.postRotate((float) location.getDirection(), bw / 2, bh / 2);
        Bitmap bitmapNew = Bitmap.createBitmap(bitmap, 0, 0, bw, bh, matrix, true);
        //bitmap.recycle();
        return bitmapNew;
    }

    private void googleAnimateTo(double latitude, double longitude) {
        if (latitude == 0 && longitude == 0) {
            L.GL.w("invalid location");
            return;
        }
        Gps _gps = /*PositionUtil.gps84_To_Gcj02(latitude, longitude)*/new Gps(latitude, longitude);
        // 移动到某经纬度
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new com.google.android.gms.maps.model.LatLng(
                _gps.getWgLat(),
                _gps.getWgLon()), 11);
        mGoogleMap.moveCamera(cameraUpdate);
    }

    private void googleAnimateAndAddMarker(double latitude,
                                           double longitude,
                                           int positionDrawableRes) {
        if (latitude == 0 && longitude == 0) {
            L.GL.w("invalid location");
            return;
        }
        Gps _gps = /*PositionUtil.gps84_To_Gcj02(latitude, longitude)*/new Gps(latitude, longitude);
        // 移动到某经纬度
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new com.google.android.gms.maps.model.LatLng(
                _gps.getWgLat(),
                _gps.getWgLon()), 11);
        mGoogleMap.moveCamera(cameraUpdate);

        if (positionDrawableRes > 0) {
            if (mGoogleMarker != null) {
                mGoogleMarker.remove();
            }
            //添加marker
            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(), positionDrawableRes);
            if (positionDrawableRes != R.drawable.travel_start && positionDrawableRes != R.drawable.travel_end && positionDrawableRes != R.drawable.travel_location) {
                bitmap = getDirectionBitmap(bitmap);
            }
            mGoogleMarker = mGoogleMap.addMarker(new MarkerOptions().icon(com.google.android.gms.maps.model.BitmapDescriptorFactory
                    .fromBitmap(bitmap))
                    .anchor(0.5f, 0.5f)
                    .position(new com.google.android.gms.maps.model.LatLng(
                            _gps.getWgLat(),
                            _gps.getWgLon())));
            mGoogleMarker.setZIndex(6);
        }
    }

    private void initGoogle() {
        mBinding.bmapView.setVisibility(View.GONE);
        mBinding.googleMapView.setVisibility(View.VISIBLE);
        mBinding.googleMapView.onCreate(null);
        mBinding.googleMapView.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        // 清空
        googleMap.clear();
        mGoogleMap = googleMap;
        mGoogleMap.getUiSettings().setCompassEnabled(false);
        CameraUpdate cameraUpdate = CameraUpdateFactory.zoomTo(15);
        mGoogleMap.moveCamera(cameraUpdate);
        mGoogleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(com.google.android.gms.maps.model.LatLng latLng) {
                VehicleLocationActivity.start(mContext, mData);
            }
        });
        mGoogleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                VehicleLocationActivity.start(mContext, mData);
                return true;
            }
        });
        updateUi();
        onResume();
    }

    /**
     * GPS定位
     */
    private void updateGpsSignal() {
        int count = mData.getSignalSpan();
        if (count < 4) {
            count = 0;
        } else if (count >= 4 && count < 6) {
            count = 1;
        } else if (count >= 6 && count < 8) {
            count = 2;
        } else if (count >= 8 && count < 10) {
            count = 3;
        } else if (count >= 10 && count < 12) {
            count = 4;
        } else if (count >= 12) {
            count = 5;
        }
        mBinding.gpsSignal.setSignal(count, R.drawable.gps_signal_bg_gray);
    }

    /**
     * 基站定位
     */
    private void updateGsmSignal() {
        int count = mData.getMcc();
        if (count < 0) {
            count = 0;
        }
        if (count > 5) {
            count = 5;
        }
        mBinding.mccSignal.setSignal(count, R.drawable.gps_signal_bg_gray);
    }

    @Override
    public void onGetPointAddress(boolean success, String addr, Object extra) {
        Location location = mData;
        if (location == null) {
            return;
        }
        L.GL.d("address:%s", addr);
        location.setAddress(addr);
        if (!success) {
            mBinding.tvAddress.postDelayed(() -> new BaiduUtil(this).getAddress(location.getLatitude(),
                                                                                location.getLongitude(),
                                                                                location), 1000);
        }
    }

    @Override
    public void onHttpSuccess(HttpTask httpTask, Object entity) {
        super.onHttpSuccess(httpTask, entity);
        String method = httpTask.getMethod();
        if (method.equals(CommonRequest.METHOD_GET_ADDRESS)) {
            Address address = (Address) entity;
            mData.setAddress(address.getData());
        }
    }

    public void onResume() {
        if (mUseBaidu) {
            mBinding.bmapView.onResume();
        } else {
            mBinding.googleMapView.onResume();
        }
    }

    public void onPause() {
        if (mUseBaidu) {
            mBinding.bmapView.onPause();
        } else {
            mBinding.googleMapView.onPause();
        }
    }

    public void onDestroy() {
        if (mUseBaidu) {
            mBinding.bmapView.onDestroy();
        } else {
            mBinding.googleMapView.onDestroy();
        }
    }

    @Override
    public void onClick(View v) {
        int vid = v.getId();
        if (vid == R.id.iv_map_cover) {
            VehicleLocationActivity.start(mContext, mData);
        }
    }
}
